<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
   <link rel="stylesheet" type="text/css" href="stylesheet.css"/>
   <script type="text/javascript" src="js/pageToc.js"></script>
   <script type="text/javascript" src="js/sh/scripts/shCore.js"></script>
   <script type="text/javascript" src="js/sh/scripts/shBrushJScript.js"></script>
   <script type="text/javascript" src="js/sh/scripts/shBrushPhp.js"></script>
   <script type="text/javascript" src="js/sh/scripts/shBrushPlain.js"></script>
   <script type="text/javascript" src="js/sh/scripts/shBrushXml.js"></script>
   <link type="text/css" rel="stylesheet" href="js/sh/styles/shCore.css"/>
   <link type="text/css" rel="stylesheet" href="js/sh/styles/shThemeDefault.css"/>
   <script type="text/javascript">
   		SyntaxHighlighter.config.clipboardSwf = 'js/sh/scripts/clipboard.swf';
   		SyntaxHighlighter.all();
   </script>
   <title>PushButton Engine Lesson #3: Adding Control with a Custom Component</title>
</head>
<body>

   <h1>PushButton Engine Lesson #3: Adding Control with a Custom Component</h1>
   <p><center><em>"If you don't control your mind, someone else will."</em> - John Allston</center></p>
   
   <p>The goal of this lesson is to guide the user through adding a custom component to move a simple shape around the screen.</p>
   
   <p>These lessons are structured in a series of steps -- small milestones that will provide focused short-term goals for incrementally understanding PushButton Engine.</p>
   
   <p>These lessons are targeted at someone who is new to PBEngine, but not necessarily new to programming.</p>
   <div id="pageToc"></div>

   <div id="contentArea">   
   
   <h2>Tutorial Resources:</h2>
   <p>To follow along with the tutorial, you can download the starter project and use it as your base to implement the tutorial:
      <ul>
         <li><a href="downloads/Lesson3Base.zip">Lesson3Base.zip</a> (2KB)</li>
      </ul>
   The completed lesson files are available at the end of the tutorial.
   </p>
   <p>As covered in Lesson 1, extract the example .zip into a personal project folder, and ensure that it builds in your build environment.</p>
   
   <p>The built .swf of the base starter project should display a blue circle in the upper left corner of the screen.</p>
   
   <h2>Introduction to the Tutorial</h2>
   
   <p><img src="images/Lesson3_Coordinates.png" alt="World Coordinates Diagram" align="right"></a></p>
   <p>One of the strengths of PushButton Engine lies in the flexible way that components add functionality to a game.  In this tutorial, we will make a relatively simple movement component.  Later tutorials will deal with user input and handling collisions, but this lesson will keep things relatively basic.</p>
   
   <p>The starter project for this lesson is <em>very close</em> to the previous lesson, except that the ball now spawns in the upper left corner of the screen.  The location for the ball is (-375,-275).  The reason for the odd number is to place the ball at half of its radius (25) from the edge of the screen, to be perfectly in the corner.  You can refer to the diagram for an overview of this example's screen coordinates.</p>
   
   <h2>Building a Component</h2>
   <p>As in the previous example, we will set up a basic scene.  Our Hero component will have three components: a render component, a spatial component, and a controller component (the new DemoControllerComponent).</p>
   <p>This new controller component will make our entity move in a zig-zag fashion down the screen, similar to an Invaders enemy.</p>
   <p>To build our new component, we must create a class for it.  To get basic component features, you must inherit from one of the base component classes.  For the type of component that we want in this example, we will inherit from TickedComponent.  Components that descend from TickedComponent get their onTick() method called 30 times per second.  This makes it a logical place to put movement logic.</p>
   <p>So every 33 milliseconds, the onTick() method of the controller component is called.  This method handles the housekeeping for checking boundaries, and moving the parent entity.  It looks at the position of the parent entity (gotten from the spatial component), and then applies some rules to create some simple movement behavior:</p>
   <p>
   <ul>
      <li>If we are on the left edge:
         <ul>
            <li>Turn to the right</li>
            <li>Move down a notch</li>
         </ul>
      </li>
      <li>If we are on the right edge:
         <ul>
            <li>Turn to the left</li>
            <li>Move down a notch</li>
         </ul>
      </li>
      <li>Move in the direction that we're heading</li>
   </ul>
   </p>
   <p>Now that we know the basic plan, let's put it into action!  Create a new source file in the project's source directory with the name DemoControllerComponent.as, and use the following code listing for the file:</p>
   <p><strong>File: /Lesson3Base/Source/DemoControllerComponent.as</strong></p>
   <pre class="brush: js">
       package 
       {
          import com.pblabs.engine.components.TickedComponent;
          import com.pblabs.engine.entity.PropertyReference;

          import flash.geom.Point;

          // Make a ticked component so that it can update itself every frame with onTick() 
          public class DemoControllerComponent extends TickedComponent
          {
             // Keep a property reference to our entity's position.
             public var positionReference:PropertyReference;

             // Store the direction that our entity is traveling: 1 is to the right, -1 is to the left.
             private var direction:int = 1;   

             // onTick() is called every frame
             public override function onTick(tickRate:Number):void
             {
                // Copy the owner entity's position into a local Point structure
                var position:Point = owner.getProperty(positionReference);

                // If we are over the left edge...
                if (position.x < -375) {
                   // ...then push ourselves to the right for the time being.
                   direction = 1;

                   // Move our entity down a notch
                   position.y += 20;
                }
                // If we are over the right edge...
                else if (position.x > 375) {
                   // ...then push ourselves to the left for the time being.
                   direction = -1;

                   // Move our entity down a notch
                   position.y += 20;
                }

                // Move 5 units in the direction that we're headed
                position.x += direction * 5;

                // Set the spatial component's position based on our new value
                owner.setProperty(positionReference, position);
             }

          }
       }
   </pre>   
   
   <h2>Connecting the Dots</h2>
   <p>Now that we've created our component, it's time to add it into our game!  We will add this component to our Hero entity in the same way that we added the other components in Lesson 2.</p>

   <p>At the bottom of createHero(), after the last call to hero.AddComponent(), add the following lines:</p>
   
   <p><strong>File: /Lesson3Base/Source/Lesson3Base.as</strong></p>
   <pre class="brush: js">
       var controller:DemoControllerComponent = new DemoControllerComponent();

       // Point the controller component to this entity's Spatial component for position information
       controller.positionReference = new PropertyReference("@Spatial.position");

       // Add the demo controller component to the Hero entity with the name "Controller"
       hero.addComponent( controller, "Controller" );
   </pre>      
   
   <p>This creates an instance of the new DemoControllerComponent(), connects the position reference to the entity's spatial component, and adds the component to the entity.</p>
   
   <p>And that's it!  Only thing left now is to compile and run.</p>

   <h2>Seeing it in action.</h2>
   <p>After compilation, you should produce a .swf like the following (click to load):</p>
   <p><a href="downloads/Lesson3Final.swf"><img src="images/Lesson3_1.png" width="204" height="159" alt="Our shiny circle!"></a></p>
   
   <h2>Conclusion</h2>
   
   <p>Congratulations!  You have finished lesson #3, made your first custom component, and seen it in action.</p>

   <p>You can download the completed project source files for this project.
      <ul>
         <li><a href="downloads/Lesson3Final.zip">Lesson3Final.zip</a> (3KB)</li>
      </ul>
   </p>
   </div>
</body>
</html>